﻿Imports System.Text
Imports System.Security.Cryptography
Imports System.ComponentModel
Imports Npgsql

Public Enum AuthResult
    AUTH_OK
    NOT_TECH
    UNAUTH
End Enum

Public Class clsUser
    Private _userID As Integer
    Private _userName As String
    Private _password As String
    Private _firstName As String
    Private _lastName As String
    Private _userEmail As String
    Private _isTech As Boolean
    Private _Authenticated As Boolean = False

#Region "Properties"
    Public ReadOnly Property UserID() As Integer
        Get
            Return _userID
        End Get
    End Property

    Public Property UserName As String
        Get
            Return _userName
        End Get
        Set(ByVal value As String)
            _userName = value
        End Set
    End Property

    Public Property Password As String
        Get
            Return _password
        End Get
        Set(ByVal value As String)
            _password = value
        End Set
    End Property

    Public Property FirstName As String
        Get
            Return _firstName
        End Get
        Set(ByVal value As String)
            _firstName = value
        End Set
    End Property

    Public Property LastName As String
        Get
            Return _lastName
        End Get
        Set(ByVal value As String)
            _lastName = value
        End Set
    End Property

    Public Property UserEmail As String
        Get
            Return _userEmail
        End Get
        Set(ByVal value As String)
            _userEmail = value
        End Set
    End Property

    Public Property IsTech As Boolean
        Get
            Return _isTech
        End Get
        Set(ByVal value As Boolean)
            _isTech = value
        End Set
    End Property
    Public ReadOnly Property Authenticated As Boolean
        Get
            Return _Authenticated
        End Get
    End Property
#End Region

#Region "Methods"
    Public Sub New()

    End Sub
    Public Sub New(ByVal username As String)
        _userName = username
        _retrieveUserData()
    End Sub
    Public Sub New(ByVal username As String, ByVal useremail As String, ByVal firstname As String, ByVal lastname As String, ByVal password As String, ByVal tech As Boolean)
        _userName = username
        _userEmail = useremail
        _firstName = firstname
        _lastName = lastname
        _password = password
        _isTech = tech

        _addUser()
    End Sub
    Public Function Authenticate(ByVal Password As String) As AuthResult
        Select Case (UCase(GenerateMD5Hash(Password)) = UCase(_password))
            Case True
                If _isTech Then
                    _Authenticated = True
                    Return AuthResult.AUTH_OK
                Else
                    _Authenticated = False
                    Return AuthResult.NOT_TECH
                End If
            Case Else
                Return AuthResult.UNAUTH
        End Select
    End Function
    Public Sub EditUser(ByVal userid As Integer, ByVal firstName As String, ByVal lastName As String, ByVal useremail As String, ByVal username As String, ByVal istech As Boolean)
        Try
            ' Create Npgsql connection with connection string from UIBase
            Dim conn As New NpgsqlConnection(clsUIBase.DBConnString)

            ' Open the connection
            conn.Open()

            Dim sql As String = "UPDATE public.users SET firstname = '" & firstName & "', lastname = '" & lastName & "', useremail = '" & useremail & "', username = '" & username & "', istech = '" & istech & "' Where Users.userid = '" & userid & "'"

            ' Create and initialize the Npgsql data adapter
            Dim da As New NpgsqlCommand(sql, conn)
            da.ExecuteNonQuery()

            ' Close the connection
            conn.Close()
        Catch ex As NpgsqlException
            ' Catch/Display any npgsql exceptions
            MessageBox.Show("SQL exception: " & ex.Message)
        Catch ex As Exception
            ' Catch/Dispaly any remaining exceptions
            MessageBox.Show("There was an error: " & ex.Message)
        End Try
    End Sub
    Public Sub ResetPassword(ByVal userid As Integer, ByVal password As String)
        Try
            ' Create Npgsql connection with connection string from UIBase
            Dim conn As New NpgsqlConnection(clsUIBase.DBConnString)

            ' Open the connection
            conn.Open()

            Dim sql As String = "UPDATE public.users SET password = '" & GenerateMD5Hash(password) & "' Where Users.userid = '" & UserID & "'"

            ' Create and initialize the Npgsql data adapter
            Dim da As New NpgsqlCommand(sql, conn)
            da.ExecuteNonQuery()

            ' Close the connection
            conn.Close()
        Catch ex As NpgsqlException
            ' Catch/Display any npgsql exceptions
            MessageBox.Show("SQL exception: " & ex.Message)
        Catch ex As Exception
            ' Catch/Dispaly any remaining exceptions
            MessageBox.Show("There was an error: " & ex.Message)
        End Try
    End Sub
#End Region

#Region "Functions and Subs"
    Private Function GenerateMD5Hash(ByVal sourceText As String) As String
        'Create an encoding object to ensure the encoding standard for the source text
        Dim Ae As New ASCIIEncoding
        'Retrieve a byte array based on the source text
        Dim ByteSourceText() As Byte = Ae.GetBytes(sourceText)
        'Instantiate an MD5 Provider object
        Dim Md5 As New MD5CryptoServiceProvider
        'Compute the hash value from the source
        Dim ByteHash() As Byte = Md5.ComputeHash(ByteSourceText)
        'And convert it to String format for return
        Return ByteArrayToString(ByteHash)
    End Function
    Private Sub _retrieveUserData()
        ' Attempt to connect to the DB to populate user properties based on username
        Try
            ' Create Npgsql connection with connection string from UIBase
            Dim conn As New NpgsqlConnection(clsUIBase.DBConnString)

            ' Open the connection
            conn.Open()

            ' Retrieve all columns from the users table pertaining to the current username from Login form
            Dim sql As String = "SELECT * FROM public.users WHERE Username='" & _userName & "'"

            ' Create and initialize the Npgsql data adapter
            Dim da As New NpgsqlDataAdapter(sql, conn)

            ' Create and fill the Data set
            Dim ds As New DataSet()
            da.Fill(ds)

            If ds.Tables(0).Rows.Count = 1 Then
                ' Pull values from the Data Set and populate the properties
                _userID = ds.Tables(0).Rows(0).Item("userid")
                '_userName = ds.Tables(0).Rows(0).Item("Username")
                _password = ds.Tables(0).Rows(0).Item("password")
                _firstName = ds.Tables(0).Rows(0).Item("firstname")
                _lastName = ds.Tables(0).Rows(0).Item("lastname")
                _userEmail = ds.Tables(0).Rows(0).Item("useremail")
                _isTech = ds.Tables(0).Rows(0).Item("istech")
                'Else
                '    ' Username does not exist, obfuscate that by not authenticating the user without telling them the username is not in the db
                '    _Authenticated = False
            End If

            ' Close the connection
            conn.Close()
        Catch ex As NpgsqlException
            ' Catch/Display any npgsql exceptions
            MessageBox.Show("SQL exception: " & ex.Message)
        Catch ex As Exception
            ' Catch/Dispaly any remaining exceptions
            MessageBox.Show("There was an error: " & ex.Message)
        End Try
    End Sub
    Private Function ByteArrayToString(ByVal arrInput() As Byte) As String
        Dim i As Integer
        Dim sOutput As New StringBuilder(arrInput.Length)
        For i = 0 To arrInput.Length - 1
            sOutput.Append(arrInput(i).ToString("X2"))
        Next
        Return sOutput.ToString()
    End Function
    Private Sub _addUser()
        Try
            ' Create Npgsql connection with connection string from UIBase
            Dim conn As New NpgsqlConnection(clsUIBase.DBConnString)

            ' Open the connection
            conn.Open()

            Dim sql As String = "INSERT INTO public.users (firstname, lastname, password, useremail, username, istech) " & _
                                "VALUES ('" & _firstName & "','" & _lastName & "','" & GenerateMD5Hash(_password) & "','" & _
                                _userEmail & "','" & _userName & "','" & _isTech & "')"

            ' Create and initialize the Npgsql data adapter
            Dim da As New NpgsqlCommand(sql, conn)
            da.ExecuteNonQuery()

            ' Close the connection
            conn.Close()
        Catch ex As NpgsqlException
            ' Catch/Display any npgsql exceptions
            MessageBox.Show("SQL exception: " & ex.Message)
        Catch ex As Exception
            ' Catch/Dispaly any remaining exceptions
            MessageBox.Show("There was an error: " & ex.Message)
        End Try
    End Sub
#End Region
End Class
